package org.judo.database.orm.mappers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import org.judo.database.Database;
import org.judo.database.JudoResultSet;
import org.judo.util.Util;

/**
 * 
 * This list is used to replace one to many list properties
 * in property objects.  It is created when an object is queried
 * or after and object is inserted.
 *
 */
public class LazyInitList implements List
{
	private ArrayList list = new ArrayList();
	private ArrayList removed = new ArrayList();
	
	private boolean inited;
	private boolean ignoreInit;
	
	private String populateSQL;
	private Class childClass;
	private ReflectionMapper sessionDB;
	
	protected void performLazyInit()
	{
		try
		{
			if (ignoreInit)
				return;
			
			JudoResultSet rs = 
				sessionDB.performQuery(populateSQL,childClass);
			
			for (int i=0;i<rs.size();i++)
				list.add(rs.get(i));
			
			inited = true;
		}
		catch(Exception e)
		{
			throw new FatalDBError(e.toString());
		}
	}
	
	public void defineChildClass(Class childClass)
	{
		this.childClass = childClass;
	}
	
	public void definePopulateSQL(String sql)
	{
		populateSQL = sql;
	}
	
	public void defineReflectionMapper(ReflectionMapper sessionDB)
	{
		this.sessionDB = sessionDB;
	}
	
	public boolean add(Object o)
	{
		if (!inited)
			performLazyInit();
		
		return list.add(o);
	}

	public void add(int index, Object element)
	{
		if (!inited)
			performLazyInit();
		
		list.add(index,element);
	}

	public boolean addAll(Collection c)
	{
		if (!inited)
			performLazyInit();
		
		return list.addAll(c);
	}

	public boolean addAll(int index, Collection c)
	{
		if (!inited)
			performLazyInit();
		
		return list.addAll(index,c);
	}

	public void clear()
	{
		if (!inited)
			performLazyInit();
		
		list.clear();
	}

	public boolean contains(Object o)
	{
		if (!inited)
			performLazyInit();
		
		return list.contains(o);
	}

	public boolean containsAll(Collection c)
	{
		if (!inited)
			performLazyInit();
		
		return list.containsAll(c);
	}

	public Object get(int index)
	{
		if (!inited)
			performLazyInit();
		
		return list.get(index);
	}

	public int indexOf(Object o)
	{
		if (!inited)
			performLazyInit();
		
		return list.indexOf(o);
	}

	public boolean isEmpty()
	{
		if (!inited)
			performLazyInit();
		
		return list.isEmpty();
	}

	public Iterator iterator()
	{
		if (!inited)
			performLazyInit();
		
		return list.iterator();
	}

	public int lastIndexOf(Object o)
	{
		if (!inited)
			performLazyInit();
		
		return list.lastIndexOf(o);
	}

	public ListIterator listIterator()
	{
		if (!inited)
			performLazyInit();
		
		return list.listIterator();
	}

	public ListIterator listIterator(int index)
	{
		if (!inited)
			performLazyInit();
		
		return list.listIterator(index);
	}

	public boolean remove(Object o)
	{
		if (!inited)
			performLazyInit();
		
		removed.add(o);
		
		return list.remove(o);
	}

	public Object remove(int index)
	{
		if (!inited)
			performLazyInit();
		
		Object obj = list.get(index);
		removed.add(obj);
		
		return list.remove(index);
	}

	public boolean removeAll(Collection c)
	{
		if (!inited)
			performLazyInit();
		
		removed.addAll(c);
		
		return list.removeAll(c);
	}

	public boolean retainAll(Collection c)
	{
		if (!inited)
			performLazyInit();
		
		return list.retainAll(c);
	}

	public Object set(int index, Object element)
	{
		if (!inited)
			performLazyInit();
		
		return list.set(index,element);
	}

	public int size()
	{
		if (!inited)
			performLazyInit();
		
		return list.size();
	}

	public List subList(int fromIndex, int toIndex)
	{
		if (!inited)
			performLazyInit();
		
		return list.subList(fromIndex,toIndex);
	}

	public Object[] toArray()
	{
		if (!inited)
			performLazyInit();
		
		return list.toArray();
	}

	public Object[] toArray(Object[] a)
	{
		if (!inited)
			performLazyInit();
		
		return list.toArray(a);
	}

	public void startIgnoreInit()
	{
		ignoreInit = true;		
	}
	
	public void endIgnoreInit()
	{
		ignoreInit = false;		
	}
}
